package deibay.server;


import java.util.HashMap;
import java.util.LinkedList;
import java.util.Iterator;
import java.util.logging.Level;

import deibay.DeibayLogger;
import deibay.messages.ReplySubscribeItemMsg;
import deibay.server.events.BiddingItemEvent;
import deibay.server.events.Event;
import deibay.server.events.CreateSessionEvent;
import deibay.server.events.NewItemEvent;
import deibay.server.events.ReceivedMessageEvent;
import deibay.server.events.RemoveItemEvent;
import deibay.server.events.RemoveSessionEvent;
import deibay.server.events.SendAdvertiseEvent;
import deibay.server.events.SendMessageEvent;
import deibay.server.events.SubscribeItemEvent;


public class EventManager {	
		
	private HashMap<Class, LinkedList<EventConsumer>> listeners = null;
	
	public EventManager()
	{
		try
		{
			listeners = new HashMap<Class, LinkedList<EventConsumer>>();						
		}
		catch (Exception exc)
		{			
			DeibayLogger.getInstance().getLog().log(Level.SEVERE, "" + exc.getMessage());		
		}		
	}
	
	public void init()
	{
		publish();	
	}
	
	public synchronized void fireEvent(final Event event)
	{	
		LinkedList consumers = listeners.get(event.getClass());
		
		if(consumers == null)
			return;
		
		for(Iterator i = consumers.iterator(); i.hasNext();)
		{
			final EventConsumer consumer = (EventConsumer)i.next();
			//System.err.println("forwarding to " + consumer);
			consumer.handleEvent(event);
		}
		
		DeibayLogger.getInstance().getLog().log(Level.WARNING, "Foi disparado o evento "+event.toString()+".\n");
	}
	
	public void publish()
	{
		listeners.put(CreateSessionEvent.class, new LinkedList<EventConsumer>());
		listeners.put(ReceivedMessageEvent.class, new LinkedList<EventConsumer>());
		listeners.put(SendMessageEvent.class, new LinkedList<EventConsumer>());
		listeners.put(RemoveSessionEvent.class, new LinkedList<EventConsumer>());
		listeners.put(BiddingItemEvent.class, new LinkedList<EventConsumer>());	
		listeners.put(SubscribeItemEvent.class, new LinkedList<EventConsumer>());
		listeners.put(ReplySubscribeItemMsg.class, new LinkedList<EventConsumer>());	
		listeners.put(NewItemEvent.class, new LinkedList<EventConsumer>());
		listeners.put(RemoveItemEvent.class, new LinkedList<EventConsumer>());
		listeners.put(SendAdvertiseEvent.class, new LinkedList<EventConsumer>());
	}
	
	public synchronized void unPublish(Class event)
	{
		listeners.remove(event);
	}
	
	public synchronized void subscribe(final EventConsumer consumer, Class event)
	{
		LinkedList<EventConsumer> consumers = listeners.get(event);
		consumers.add(consumer);
		DeibayLogger.getInstance().getLog().log(Level.INFO, "Consumidor ["+consumer.getClass().getCanonicalName()+"] inscreveu-se ao evento ["+event.getCanonicalName()+"].\n");
	}
	
	public synchronized void unSubscribe(EventConsumer consumer, Class event)
	{
		LinkedList consumers = listeners.get(event);
		consumers.remove(consumer);		
	}
}
